//
//  TakePhotoViewController.swift
//  ezyform
//
//  Created by MoennigQ on 28/2/19.
//  Copyright © 2019 Client.Solution Pty Ltd. All rights reserved.
//

import UIKit
import AVFoundation
import HandyJSON
import CoreLocation
import Photos
import PhotosUI
class TakePhotoViewController: BaseViewController {
    var takePhotoClosure: ((UIImage)->Void)?
    var selectPhotosFromLibraryClosure: ((PHAsset)->Void)?
    let customView = TakePhotoView()
    var defaultUseFrontCameraFlag: Bool = false//是否默认使用前置摄像头
    var usingFrontCamera: Bool = false//当前摄像头是否是前置摄像头，用户切换摄像头
    var photosCnt: Int = 0//已有的拍照数量
    var naviTitle: String = ""//导航标题
    //
    var backCamera: AVCaptureDevice?
    var frontCamera: AVCaptureDevice?
    var currentCamera: AVCaptureDevice?
    var captureSession: AVCaptureSession! = AVCaptureSession()
    var photoOutput: AVCapturePhotoOutput?
    var cameraPreviewLayer: AVCaptureVideoPreviewLayer?
    var maxCount: Int = 10//选择图库时，最多选择几张图片
    override func viewDidLoad() {
        super.viewDidLoad()
        setupDevice()
        setupUI()
        //进入take photo获取一次定位信息
        Tool().requestCurrentLocation()
    }
    private func setupUI(){
        self.view.backgroundColor = .black
        self.view.addSubview(customView)
        //
        customView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        self.customView.photoCntLabel.text = String(self.photosCnt)
        self.customView.setTakePhotoTitle(self.naviTitle)
        self.customView.takePhotoBtn.addTarget(self, action: #selector(takePhotoBtnClick), for: UIControl.Event.touchUpInside)
        self.customView.takePhotoBtn.isUserInteractionEnabled = false//默认不可交互，startRunning后再开启
        //
        self.customView.swithCamaraBtn.addTarget(self, action: #selector(switchCamara), for: UIControl.Event.touchUpInside)
        self.customView.returnBtn.addTarget(self, action: #selector(returnBtnClick), for: UIControl.Event.touchUpInside)
        //跳转到select photo from library界面
        self.customView.photoImageViewClickClosure = {[weak self] in
            guard let strongSelf = self else { return  }
            PhotosManager.shared.initData(vc: strongSelf, maxCount: strongSelf.maxCount, closure: {  (pHAssert, errmsg) in
                if let _ = errmsg{
                    Tool().showAlertViewWithOneBtn(message: errmsg!)
                }else if let data = pHAssert as? PHAsset{
                    strongSelf.selectPhotosFromLibraryClosure?(data)
                }
            }).getPhotos(assertFLag: true)
        }
        //防止拿不到摄像头（设备损坏原因），app crash
        if let _ = self.currentCamera {
            self.customView.noAvailableDeviceLabel.isHidden = true
            setupInputOutPut()
            setupPreviewLayer()
            
            DispatchQueue.main.async {[weak self] in
                guard let strongSelf = self else { return  }
                strongSelf.captureSession.startRunning()
                strongSelf.customView.enableTakePhotoBtn()
            }
        }else{
            self.customView.noAvailableDeviceLabel.isHidden = false
        }
    }
    @objc
    func takePhotoBtnClick(){
        guard let _ = self.currentCamera else {
            Tool().showAlertViewWithOneBtn(message: R.string.localizable.noCameraAvailable())
            return
        }
        if let _ = self.photoOutput {
            self.customView.disableTakePhotoBtn()
            let settings = AVCapturePhotoSettings()
            photoOutput?.capturePhoto(with: settings, delegate: self)
            //处理拍照动画效果
            DispatchQueue.main.async {
                UIView.animate(withDuration: 0.1, delay: 0, options: UIView.AnimationOptions.transitionCrossDissolve) {[weak self] in
                    guard let strongSelf = self else { return  }
                    strongSelf.customView.maskLayer.alpha = 1
                } completion: { [weak self] (_ ) in
                    guard let strongSelf = self else { return  }
                    strongSelf.customView.maskLayer.alpha = 0
                }
            }
        }
    }
    
    //切换前后摄像头
    @objc
    func switchCamara() {
        do{
            if let _ = captureSession.inputs.first {
                captureSession.removeInput(captureSession.inputs.first!)
            }
            
            var captureDevice: AVCaptureDevice!
            if(usingFrontCamera){
                usingFrontCamera = false
                captureDevice = getBackCamera()
            }else{
                usingFrontCamera = true
                captureDevice = getFrontCamera()
            }
            if let _ = captureDevice{
                self.customView.noAvailableDeviceLabel.isHidden = true
                let captureDeviceInput1 = try AVCaptureDeviceInput(device: captureDevice)
                captureSession.addInput(captureDeviceInput1)
            }else{
                self.customView.noAvailableDeviceLabel.isHidden = false
            }
            
        }catch{
            print(error.localizedDescription)
        }
        
        
    }
    private func getFrontCamera() -> AVCaptureDevice?{
        return AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .front).devices.first
        
    }

    private func getBackCamera() -> AVCaptureDevice?{
        return AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .back).devices.first
        
    }
    @objc
    func returnBtnClick(){
        DispatchQueue.main.async {[weak self] in
            guard let strongSelf = self else { return  }
            strongSelf.captureSession.stopRunning()
        }
        self.navigationController?.popViewController(animated: true)
    }
    
    private func setupDevice(){
        let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.Position.unspecified)
        let devices = deviceDiscoverySession.devices
        
        for device in devices {
            if device.position == AVCaptureDevice.Position.back {
                self.backCamera = device
            }else if device.position == AVCaptureDevice.Position.front{
                self.frontCamera = device
            }
        }
        //默认开启前置蛇形头
        if self.defaultUseFrontCameraFlag {//需要自拍时且前置摄像头可用，就开启前置摄像头，否则开启后置摄像头
            if let _ = self.frontCamera, UIImagePickerController.isCameraDeviceAvailable(UIImagePickerController.CameraDevice.front){//
                self.currentCamera = self.frontCamera
                self.usingFrontCamera = true
            }else {//前置摄像头无效
                self.customView.noAvailableDeviceLabel.isHidden = false
            }
            
        }else {//否则默认开启后置摄像头
            if let _ = self.backCamera, UIImagePickerController.isCameraDeviceAvailable(UIImagePickerController.CameraDevice.rear){
                self.currentCamera = self.backCamera
            }else{//后置摄像头无效
                self.customView.noAvailableDeviceLabel.isHidden = false
            }
        }
    }
    private func setupInputOutPut(){
        do {
            let captureDeviceInput = try AVCaptureDeviceInput(device: currentCamera!)
            captureSession.addInput(captureDeviceInput)
            photoOutput = AVCapturePhotoOutput()
            self.captureSession.sessionPreset = .photo
            photoOutput?.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecType.jpeg] )], completionHandler: nil)
            captureSession.addOutput(photoOutput!)
        }catch{
            print(error)
        }
    }
    private func setupPreviewLayer(){
        cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
        cameraPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
        cameraPreviewLayer?.frame = CGRect(x: 0, y: 0, width: APPConfig.WidthForPortrait, height: APPConfig.HeightForPortrait)
        self.view.layer.insertSublayer(cameraPreviewLayer!, at: 0)
    }
    
    //必须在 Info.plist 文件中添加 View controller-based status bar appearance ，并且必须设置为 YES
    override var prefersStatusBarHidden: Bool {
        return false
    }
    override func viewWillDisappear(_ animated: Bool) {
        captureSession.stopRunning()
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        DebugLog("\(self) didReceiveMemoryWarning")
    }
    deinit{
        if let _ = self.captureSession {
            self.captureSession.stopRunning()
            self.captureSession = nil
        }
        self.backCamera = nil
        self.frontCamera = nil
        self.currentCamera = nil
        self.cameraPreviewLayer = nil
        self.photoOutput = nil
        DebugLog("deinit")
    }
}
extension TakePhotoViewController: AVCapturePhotoCaptureDelegate{
    @available(iOS 11.0, *)
    func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
        if error == nil {//
            self.customView.enableTakePhotoBtn()
            if let imageData = photo.fileDataRepresentation(),let image = UIImage(data: imageData){
                self.dealAfterTakingPhoto(image)
            }
        }
    }
    fileprivate func dealAfterTakingPhoto(_ image : UIImage){
        self.takePhotoClosure?(image)
        self.photosCnt += 1
        self.customView.photoCntLabel.text = "\(self.photosCnt)"
    }
}
